#include "./log.h"



log::log():m_count(0),m_is_async(false)
{
}

log::~log()
{
    if(m_fp!=nullptr)
    {
        fclose(m_fp);
    }
}


log* log::get_instance()
{
    static log instance;
    return &instance;
}

void* log::async_write_log()
{
    string single_log;

    while(m_log_queue->pop(single_log))
    {
        m_mutex.lock();
        fputs(single_log.c_str(),log_fp);
        m_mutex.unlock();
    }
}

void* log::flush_log_thread(void * args)
{
    get_instance()->async_write_log();
}




bool log::init(const char * file_name,int close_log,int log_buf_size, int split_lines,int max_queue_size)
{
    if(max_queue_size>=1)
    {
        //传入大于1的参数设置为异步
        m_is_async = true;
        m_log_queue = new BlockQueue<string>(max_queue_size);

        pthread tid;
        pthread_create(&tid,NULL,flush_log_thread,NULL)
    }




    m_close_log = close_log;
    m_log_buf_size = log_buf_size;
    m_split_lines = split_lines;
    
    m_buf = new char[m_log_buf_size];
    memset(m_buf,'\0',m_log_buf_size);
    
    time_t t = time(NULL);
    struct tm *sys_tm - localtime(&t);
    struct tm my_tm = *sys_tm;

    const char * p = strrchr(file_name,'/'); //获取当前目录名
    char log_full_name[256] = {0};

    f (p == NULL)
    {
        snprintf(log_full_name, 255, "%d_%02d_%02d_%s", my_tm.tm_year + 1900, my_tm.tm_mon + 1, my_tm.tm_mday, file_name);
    }
    else
    {
        strcpy(log_name, p + 1); //获取的包括'/' 所以+1
        strncpy(dir_name, file_name, p - file_name + 1);
        snprintf(log_full_name, 255, "%s%d_%02d_%02d_%s", dir_name, my_tm.tm_year + 1900, my_tm.tm_mon + 1, my_tm.tm_mday, log_name);
    }
    m_today = my_tm.tm_mday;
    m_fp = fopen(log_full_name,"a");
    if(m_fp == NULL)
    {
        return false;
    }
    return true;
}


void log::write_log(int level,const  char *format,...)
{
    //时间获取
    struct timeval now - {0,0};
    gettimeofday(&now,NULL);
    time_t t = now.tv_sec;

    struct tm *sys_tm = localtime(&t);
    struct tm my_tm = *sys_tm;

    char s[16] = {0};

    switch (level)
    {
    case 0:
        strcpy(s,"[DEBUG]:");
        break;
    case 1:
        strcpy(s,"[INFO]:");
        break;
    case 2:
        strcpy(s,"[WARNNING]:");
        break;
    case 3:
        strcpy(s,"[ERROR]:");
        break;
    default:
        strcpy(s,"[INFO]:");
        break;
    }

    m_mutex.lock();
    //没写一行日志记录
    m_count++;
    //日志文件新建
    if(m_today!=my_tm.tm_mday || m_count%m_split_lines == 0)
    {
        char new_log[256] = {0};
        fflush(m_fp);
        fclose(m_fp);

        char tail[16] = {0};

        snprintf(tail,16,"%d_%02d_%02d_",my_tm.tm_year+1900,my_tm.tm_mon+1,my_tm.tm_mday);

        if(m_today != my_tm.tm_mday)
        {
            snprintf(new_log,255,"%s%s%s",dir_name,tail,log_name);
            m_today = my_tm.tm_mday;
            m_count=0;
        }

        else
        {
            snprintf(new_log,255,"%s%s%s.%lld",dir_name,tail,log_name,m_count/m_split_lines);
        }

        //同步写入 
        m_fp = fopen(new_log,"a");
    }

    m_mutex.unlock();

    //可变参数
    va_list valst;
    va_start(valst,format);

    string log_str;
    m_mutex.lock();

    //写入的具体内容格式
    int n = snprintf(m_buf, 48, "%d-%02d-%02d %02d:%02d:%02d.%06ld %s ",
                     my_tm.tm_year + 1900, my_tm.tm_mon + 1, my_tm.tm_mday,
                     my_tm.tm_hour, my_tm.tm_min, my_tm.tm_sec, now.tv_usec, s);
    
    int m = vsnprintf(m_buf+n,m_log_buf_size-1,format,valst);
    m_buf[m+n] = '\n';
    m_buf[m+n+1] = '\0';
    log_str = m_buf;

    m_mutex.unlock();
    
    //异步或者同步？

    if(m_is_async && !m_log_queue->full())
    {
        m_log_queue->push(log_str);
    }
    else
    {
        m_mutex.lock();
        fputs(log_str.c_str(),m_fp);
        m_mutex.unlock();
    }

    va_end(valst);
}


void log::flush(void)
{
    m_mutex.lock();
    fflush(m_fp);
    m_mutex.unlock();
}



